package com.qianfeng.iot.gateway.filters;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.dc3.common.constant.ServiceConstant;
import com.qianfeng.iot.openfeign.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * Created by Jackiechan on 2022/7/19 15:03
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
public class AuthenGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenGatewayFilterFactory.Config> {


    private AuthenFilter authenFilter;

    @Autowired
    public void setAuthenFilter(AuthenFilter authenFilter) {
        this.authenFilter = authenFilter;
    }

    @Override
    public GatewayFilter apply(Config config) {

        return authenFilter;

    }

    public static class Config {
        //自定义的config,根据我们的实际情况可以声明一些变量,在使用过滤器的时候传递进来
    }

    @Component
    static class AuthenFilter implements GatewayFilter, Ordered {
        private UserClient userClient;

        @Autowired
        public void setUserClient(UserClient userClient) {
            this.userClient = userClient;
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //过滤,可以在这里对用户的令牌进行过滤
            //首先得获取到用户的令牌
            //令牌我们要求客户端通过请求头传递,
            String jwtToken = exchange.getRequest().getHeaders().getFirst(ServiceConstant.Header.X_AUTH_TOKEN);
            //请求检查令牌的服务,对令牌进行检查,然后再决定如何处理
            // Mono<R> checkResult = userClient.checkToken(jwtToken);
            //返回的结果中只有非0才可以继续,0是不能继续的
            return Mono.just(jwtToken == null ? "" : jwtToken)
                    .flatMap(s -> userClient.checkToken(s))//去请求认证服务器进行检查,检查成功会返回1,失败会返回0
//                    .flatMap(r -> {
//                        if (((Integer) r.getData()) != 0) {
//                            return chain.filter(exchange);
//                        } else {
//                            return exchange.getResponse().writeAndFlushWith(Mono.just(Mono.just(DefaultDataBufferFactory.sharedInstance.allocateBuffer().write("尚未登录,请登录".getBytes(StandardCharsets.UTF_8)))));
//                        }
//                    })
                    .filter(r -> ((Integer) r.getData()) != 0)
                    .map(r->chain.filter(exchange))
                    .defaultIfEmpty(exchange.getResponse().writeAndFlushWith(Mono.just(Mono.just(DefaultDataBufferFactory.sharedInstance.allocateBuffer().write("尚未登录,请登录".getBytes(StandardCharsets.UTF_8)))))).flatMap(r->r);
            // .filter(r-> ((Integer) r.getData())!=0)//首先我们只要不为0的数据,也就是正常的数据
            // .flatMap(r -> chain.filter(exchange))//正常的情况就是继续
            //如果上面没有数据,说明是被过滤器给过滤掉了,也就是没有认证成功.我们就直接返回数据,结束请求
            // .switchIfEmpty(exchange.getResponse().writeAndFlushWith(Mono.just(Mono.just(DefaultDataBufferFactory.sharedInstance.allocateBuffer().write("尚未登录,请登录".getBytes(StandardCharsets.UTF_8))))));//如果检查失败就返回数据
        }

        @Override
        public int getOrder() {
            return 0;
        }
    }

}
